package com.terry;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;

import java.io.File;
import java.io.IOException;

public class Mp4Recorder implements IRecorder,Runnable{


    private SettingInfo mInfo;

    private File currentFile;

    private FFmpegFrameRecorder recorder = null;

    private FFmpegFrameGrabber grabber = null;

    private boolean mRunning = false;

    private RecorderListener mRecorderListener;

    @Override
    public void start(SettingInfo info,RecorderListener listener) {
        this.mInfo = info;
        mRunning = true;
        this.mRecorderListener = listener;
        new Thread(this).start();
    }


    @Override
    public void stop() {
        mRunning = false;
        try{
            if(recorder != null){
                recorder.stop();
            }

            if(grabber != null){
                grabber.stop();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    private void startRecorder(){
        grabber = new FFmpegFrameGrabber(mInfo.getRtspFilePath());
        //grabber.setOption("timeout","200000000");
        try{
            recordByFrame(grabber);
        }catch (Exception e){
            e.printStackTrace();
            if(this.mRecorderListener != null){
                mRecorderListener.onError(e);
            }
        }



    }


    private File getNextFile(){
        String filePath = mInfo.getFileNamePrefix() + DateTools.getTimeString()+".mp4";
        return new File(mInfo.getFileDirPath(),filePath);
    }


    private FFmpegFrameRecorder getRecorder(FFmpegFrameGrabber grabber) throws IOException {
        if(currentFile == null || (mInfo.getMaxSingleFileSize() != 0 && currentFile.length() >= mInfo.getMaxSingleFileSize()) ){

            // 文件已经达到设置值，重新开一个录制器
            if(currentFile != null){
                if(recorder != null){
                    recorder.stop();
                }
            }

            currentFile = getNextFile();
            if(currentFile.exists()){
                currentFile.delete();
            }
            currentFile.createNewFile();
            recorder = new FFmpegFrameRecorder(currentFile,grabber.getAudioChannels());

            recorder.setImageHeight(grabber.getImageHeight());
            recorder.setImageWidth(grabber.getImageWidth());

            recorder.start();
        }

        return recorder;

    }


    private  void recordByFrame(FFmpegFrameGrabber grabber)
            throws Exception {
        try {//建议在线程中使用该方法
            grabber.start();
            Frame frame = null;
            while (mRunning && (frame = grabber.grabFrame()) != null) {
                getRecorder(grabber).record(frame);
            }
            stop();

            if(this.mRecorderListener != null){
                mRecorderListener.onFinish();
            }

        } finally {
            if (grabber != null) {
                grabber.stop();
            }
        }
    }


    @Override
    public void run() {
        startRecorder();
    }
}
